﻿// =========================================================================
// Created by NYIDE.
// User: Administrator
// Date: 3/22/2022
// Description:
// =========================================================================

#include"color.h"
#include <ny8.h>
#include "NY8_constant.h"

#define SAVE_COLOR_MODE 0x01
#define SAVE_COLOR_TEMP_WARM 0x02
#define SAVE_COLOR_TEMP_COLD 0x03
#define SAVE_COLOR_RGB_RED 0x04
#define SAVE_COLOR_RGB_GREEN 0x05
#define SAVE_COLOR_RGB_BLUE 0x06
#define SAVE_COLOR_BRIGHTNESS 0x07


/*
typedef struct Color_stuct {
	uint8 mode;
	union ColorType {
		struct ColorTemp_t colorTemp;
		struct ColorRGB_t colorRGB;
	}color;
}Color_t;
void setColor(Color_t* color);
*/

extern unsigned char whitePwmState;
extern unsigned char whitePwmDuty0;
extern unsigned char whitePwmDuty1;
extern unsigned char whitePwmDuty2;
extern unsigned char whitePwmDuty3;
extern unsigned char whitePwmRun;
//Color_t savedColor;
unsigned char savedMode;
unsigned char savedRed;
unsigned char savedGreen;
unsigned char savedBlue;
unsigned char savedRgbBrightness;
unsigned char savedWarm;
unsigned char savedCold;
unsigned char savedTempBrightness;
unsigned char step = 0;
unsigned int stepCnt = 0;
unsigned int colorUpdate = 0;

//const unsigned char redFlash[6]={100,50,0,0,0,50};
//const unsigned char greenFlash[6]={0,50,100,50,0,0};
//const unsigned char blueFlash[6]={0,0,0,50,100,50};

const unsigned char redFlash[6]={20,10,0,0,0,10};
const unsigned char greenFlash[6]={0,10,20,10,0,0};
const unsigned char blueFlash[6]={0,0,0,10,20,10};

unsigned int stepCntSaved;
unsigned char powerState = 1;

unsigned char greenPwm;
unsigned char bluePwm;
unsigned char redPwm;
unsigned char savedSpeed = 2;

unsigned char personalSavedMode = 0;
unsigned char personalSavedRed;
unsigned char personalSavedGreen;
unsigned char personalSavedBlue;
unsigned char personalSavedWarm;
unsigned char personalSavedCold;
unsigned char personalSavedBrightness;

unsigned int speedStep;

//const unsigned int speedStepValue[] = {812,1625,2437,3250,4875,6500,8125,9750,11375,13000};
const unsigned char writeDuty[] = {0,17,23,27,35,40,47,53,60,67,80};

unsigned int saved10SecondCnt;
unsigned char nightModeFlag = 0;
unsigned char autoOffModeFlag = 0;
unsigned int countDownCount;
//unsigned char nightModeDuty;

unsigned char color_eeprom_read(unsigned char addr)
{
	unsigned char ret = eeprom_read (addr);
	if(ret > 10) ret = 5;
	return ret;
}
void readColor(void)
{

	savedMode = eeprom_read (SAVE_COLOR_MODE);
	if (savedMode > COLOR_MODE_SMOTH) savedMode = COLOR_MODE_COLORTEMP;
	savedWarm = color_eeprom_read (SAVE_COLOR_TEMP_WARM);
	//savedCold = color_eeprom_read (SAVE_COLOR_TEMP_COLD);
	savedCold = 10 - savedWarm;
	savedTempBrightness = color_eeprom_read (SAVE_COLOR_BRIGHTNESS);

	savedRed = color_eeprom_read (SAVE_COLOR_RGB_RED);
	savedGreen = color_eeprom_read (SAVE_COLOR_RGB_GREEN);
	savedBlue= color_eeprom_read (SAVE_COLOR_RGB_BLUE);
	savedRgbBrightness = color_eeprom_read (SAVE_COLOR_BRIGHTNESS);
	
	personalSavedMode = eeprom_read (SAVE_PERSONAL_MODE);
	if (personalSavedMode > COLOR_MODE_COLORRGB) personalSavedMode = COLOR_MODE_COLORTEMP;
	personalSavedWarm = color_eeprom_read (SAVE_PERSONAL_COLOR_TEMP_WARM);
	personalSavedCold = 10 - personalSavedWarm;
	
	personalSavedRed = color_eeprom_read (SAVE_PERSONAL_COLOR_RGB_RED);
	personalSavedGreen = color_eeprom_read (SAVE_PERSONAL_COLOR_RGB_GREEN);
	personalSavedBlue= color_eeprom_read (SAVE_PERSONAL_COLOR_RGB_BLUE);
	personalSavedBrightness = color_eeprom_read (SAVE_PERSONAL_COLOR_BRIGHTNESS);
	
}

void writeColor(void)
{
	eeprom_protect_unlock(); 			// unlock write-protection
    //eeprom_write (SAVE_COLOR_MODE, savedMode);
    eeprom_write_timeout (SAVE_COLOR_MODE, savedMode, 5);
    if (savedMode == COLOR_MODE_COLORTEMP)
	{
		eeprom_protect_unlock(); 			// unlock write-protection
		//eeprom_write (SAVE_COLOR_TEMP_WARM, savedWarm);
		eeprom_write_timeout (SAVE_COLOR_TEMP_WARM, savedWarm, 5);
		eeprom_protect_unlock(); 			// unlock write-protection
		//eeprom_write (SAVE_COLOR_TEMP_COLD, savedCold);
		eeprom_write_timeout (SAVE_COLOR_TEMP_COLD, savedCold, 5);
		eeprom_protect_unlock(); 			// unlock write-protection
		//eeprom_write (SAVE_COLOR_BRIGHTNESS, savedRgbBrightness);
		eeprom_write_timeout (SAVE_COLOR_BRIGHTNESS, savedTempBrightness, 5);
	}
	else
	{
		eeprom_protect_unlock(); 			// unlock write-protection
		//eeprom_write (SAVE_COLOR_RGB_RED, savedRed);
		eeprom_write_timeout (SAVE_COLOR_RGB_RED, savedRed, 5);
		eeprom_protect_unlock(); 			// unlock write-protection
		//eeprom_write (SAVE_COLOR_RGB_GREEN, savedGreen);
		eeprom_write_timeout (SAVE_COLOR_RGB_GREEN, savedGreen, 5);
		eeprom_protect_unlock(); 			// unlock write-protection
		//eeprom_write (SAVE_COLOR_RGB_BLUE, savedBlue);
		eeprom_write_timeout (SAVE_COLOR_RGB_BLUE, savedBlue, 5);
		eeprom_protect_unlock(); 			// unlock write-protection
		//eeprom_write (SAVE_COLOR_BRIGHTNESS, savedRgbBrightness);
		eeprom_write_timeout (SAVE_COLOR_BRIGHTNESS, savedRgbBrightness, 5);
	}
}

void updateColor(void)
{
    unsigned char warmDuty,coldDuty,redDuty,greenDuty,blueDuty;
    static unsigned char runMode = 0xFF;
    static unsigned char lastPowerState = 0xFF;
    if(powerState == 0)
    {
    	PWM1DUTY = 0;
		PWM2DUTY = 0;
		PWM3DUTY = 0;
		PWM4DUTY = 0;
		PWM5DUTY = 0;
		runMode = savedMode;
		lastPowerState = 0;
		//return;
    }
    else
    {
		//savedMode = COLOR_MODE_FLASH;
		if (savedMode == COLOR_MODE_COLORTEMP)
		{
			//unsigned int tmp1,tmp2;
			T1CR1 &= ~C_PWM1_En; 
			P2CR1 &= ~C_PWM2_En;
			P3CR1 &= ~C_PWM3_En;
			PORTAbits.PA2 = 0;
			PORTAbits.PA4 = 0;
			PORTBbits.PB1 = 0;
	
			warmDuty = savedWarm * savedTempBrightness;
			coldDuty = savedCold * savedTempBrightness;
			//if (warmDuty > 0) warmDuty += 10;
			//if (coldDuty > 0) coldDuty += 10;
			//
			//tmp1 = transle(warmDuty);
			//tmp2 = transle(coldDuty);
			/*
			tmp1 = warmDuty;
			tmp1 = tmp1 * tmp1;
			tmp1 /= 20;
			tmp1 += 100;
			
			tmp2 = coldDuty;
			tmp2 = tmp2 * tmp2;
			tmp2 /= 20;
			tmp2 += 100;
			*/
			
			/*
			if(warmDuty != 0) 
			{
				tmp = warmDuty >> 3;
				tmp = tmp * tmp;
				warmDuty = tmp + (warmDuty >> 2) + 20;
			}
			
			if(coldDuty != 0) 
			{
				tmp = coldDuty >> 3;
				tmp = tmp * tmp;
				coldDuty = tmp + (coldDuty >> 2) + 20;
			}
			*/
			//warmDuty = writeDuty[];
			//coldDuty = writeDuty[];
			/*
			if((warmDuty == 100) && (coldDuty == 100))
			{
				//T5CR1 &= ~C_PWM5_En;
				CCPCON = 0;
				T4CR1 &= ~C_PWM4_En;
				PORTBbits.PB2 = 1;
				PORTBbits.PB3 = 1;
			}
			else if(coldDuty == 100)
			{
				//T5CR1 &= ~C_PWM5_En;
				CCPCON = 0;
				PORTBbits.PB2 = 1;
				T4CR1 |= C_PWM4_En;
				PWM4DUTY = warmDuty;
			}
			else if(warmDuty == 100)
			{
				T4CR1 &= ~C_PWM4_En;
				PORTBbits.PB3 = 1;
				//T5CR1 |= C_PWM5_En;
				CCPCON = C_CCP_PWM5_SigOut | C_CCP_PWM5_All_ActHigh;
				PWM5DUTY = coldDuty;
			}
			else*/
			{
				T4CR1 |= C_PWM4_En;
				//T5CR1 |= C_PWM5_En;
				CCPCON = C_CCP_PWM5_SigOut | C_CCP_PWM5_All_ActHigh;
				PWM4DUTY = warmDuty;
				PWM5DUTY = coldDuty;			
			}
			//writeColor();
		}
		else if(savedMode == COLOR_MODE_COLORRGB)
		{
			//T5CR1 &= ~C_PWM5_En;
			CCPCON = 0;
			T4CR1 &= ~C_PWM4_En;
			PORTBbits.PB2 = 0;
			PORTBbits.PB3 = 0;
			
			PWM3DUTY = redDuty = savedRed * savedRgbBrightness;//(savedRed * savedRgbBrightness) << 1;
			PWM1DUTY = greenDuty = savedGreen * savedRgbBrightness;//(savedGreen * savedRgbBrightness) << 1;
			PWM2DUTY = blueDuty = savedBlue * savedRgbBrightness;//(savedBlue * savedRgbBrightness) << 1;
	
	
	
			T1CR1 |= C_PWM1_En; 
			P2CR1 |= C_PWM2_En;
			P3CR1 |= C_PWM3_En;
			//writeColor();
		}
		else if(savedMode == COLOR_MODE_FLASH)
		{
			//speedStep = 406 << savedSpeed;
			speedStep = 20 << savedSpeed;
			stepCntSaved = stepCnt;
			if (runMode != savedMode || colorUpdate == 1)
			{
				colorUpdate = 0;
				
				CCPCON = 0;
				T4CR1 &= ~C_PWM4_En;
				PORTBbits.PB2 = 0;
				PORTBbits.PB3 = 0;
				
				step = 1;
				
				
				T1CR1 |= C_PWM1_En; 
				P2CR1 |= C_PWM2_En;
				P3CR1 |= C_PWM3_En;
				
				bluePwm = PWM2DUTY = blueFlash[0] * savedRgbBrightness;
				greenPwm = PWM1DUTY = greenFlash[0] * savedRgbBrightness;
				redPwm = PWM3DUTY = redFlash[0] * savedRgbBrightness;
				//writeColor();
			}
		}
		else if(savedMode == COLOR_MODE_SMOTH)
		{
			speedStep = 1 << savedSpeed;
			stepCntSaved = stepCnt;
			if (runMode != savedMode || colorUpdate == 1)
	    	{	
	    		colorUpdate = 0;
	    		
				CCPCON = 0;
				T4CR1 &= ~C_PWM4_En;
				PORTBbits.PB2 = 0;
				PORTBbits.PB3 = 0;
				
				step = 1;
				
				T1CR1 |= C_PWM1_En; 
				P2CR1 |= C_PWM2_En;
				P3CR1 |= C_PWM3_En;
				
				bluePwm = PWM2DUTY = blueFlash[0] * savedRgbBrightness;
				greenPwm = PWM1DUTY = greenFlash[0] * savedRgbBrightness;
				redPwm = PWM3DUTY = redFlash[0] * savedRgbBrightness;			
			}
		}
		lastPowerState = 1;
		runMode = savedMode;
	}
}

void colorHandler(void)
{
	if (autoOffModeFlag == 1)
	{
		//if (saved10SecondCnt + 1625 == stepCnt)
		//if (saved10SecondCnt + 1599 == stepCnt)
		if (saved10SecondCnt + 1010 == stepCnt)
		{
			saved10SecondCnt = stepCnt;
			countDownCount--;
			if(countDownCount == 0) 
			{
				powerState = 0;
				autoOffModeFlag = 0;
				updateColor();
			}
		}
	}
	if(savedMode == COLOR_MODE_FLASH)
	{
		if(stepCntSaved + speedStep == stepCnt)
		{
			step++;
			step %= 6;
			stepCntSaved = stepCnt;
			if(powerState)
			{
				PWM2DUTY = blueFlash[step] * savedRgbBrightness;
				PWM1DUTY = greenFlash[step] * savedRgbBrightness;
				PWM3DUTY = redFlash[step] * savedRgbBrightness;
			}
		}
	}
	else if(savedMode == COLOR_MODE_SMOTH)
	{
		if(stepCntSaved + speedStep == stepCnt)
		{
			//smothStep++;
			unsigned char greenFlashTemp = greenFlash[step] * savedRgbBrightness;
			unsigned char redFlashTemp = redFlash[step] * savedRgbBrightness;
			unsigned char blueFlashTemp = blueFlash[step] * savedRgbBrightness;
			stepCntSaved = stepCnt;
			if(greenPwm == greenFlashTemp && bluePwm == blueFlashTemp
				&& redPwm == redFlashTemp)
			{
				step++;
				step %= 6;
			}
			 
			{
				unsigned char up = 0, down = 0;
				if(greenPwm != greenFlashTemp)
				{
					if(greenPwm > greenFlashTemp)
					{
						greenPwm--;
						down = 1;
					}
					else if(greenPwm < greenFlashTemp)
					{
						greenPwm++;
						up = 1;
					}
				}
				if(bluePwm != blueFlashTemp)
				{
					if(bluePwm > blueFlashTemp)
					{
						if(down == 0)
						{
							bluePwm--;
							down = 1;
						}
					}
					else if(bluePwm < blueFlashTemp)
					{
						if(up == 0)
						{
							bluePwm++;
							up = 1;
						}
					}
				}
				if(redPwm != redFlashTemp)
				{
					if(redPwm > redFlashTemp)
					{
						if(down == 0)
						{
							redPwm--;
							down = 1;
						}
					}
					else if(redPwm < redFlashTemp)
					{
						if(up == 0)
						{
							redPwm++;
							up = 1;
						}
					}
				}
			}
			if(powerState)
			{
				PWM2DUTY = bluePwm;
				PWM1DUTY = greenPwm;
				PWM3DUTY = redPwm;
			}
		}
	}
	else if (savedMode == COLOR_MODE_COLORTEMP)
	{
		if (nightModeFlag == 1)
		{
			//if (saved10SecondCnt + 1625 == stepCnt)
			//if (saved10SecondCnt + 1599 == stepCnt)
			if (saved10SecondCnt + 1010 == stepCnt)
			{
				//unsigned char tmp;
				saved10SecondCnt = stepCnt;
				countDownCount--;
				/*
				tmp = 1 + (countDownCount >> 3);
				//nightModeDuty = tmp;
				//nightModeDuty = 1;
				//if (tmp > 10) PWM4DUTY = 10;
				if (tmp > 10) PWM4DUTY = 23;
				else PWM4DUTY  = tmp + 13;
				*/
				if(countDownCount == 0) 
				{
					powerState = 0;
					nightModeFlag = 0;
					updateColor();
				}
			}
		}
	}
}
void initColor(void) 
{
	IOSTB = C_PB0_Output | C_PB1_Output | C_PB2_Output | C_PB3_Output | C_PB4_Output | C_PB5_Output;
	IOSTA = C_PA2_Output | C_PA4_Output | C_PA5_Input;
	//enable PA5 PullUp 
	PCONbits.PHPA5 = 0;
	//TMRH = C_TMR1_Data_b9 | C_TMR1_Data_b8;
	readColor();
	
	
	/*
	TMR1 = 100;
	TMRH = 0;
	PWM3RH = 0;
	//T1CR2 = C_PS1_Dis | C_TMR1_ClkSrc_Inst;	// Prescaler 1:1 , Timer1 clock source is instruction clock
	T1CR2 = C_PS1_EN | C_TMR1_ClkSrc_Inst | C_PS1_Div128;
	T1CR1 = C_PWM1_Active_Hi | C_TMR1_Reload | C_TMR1_En; 
	P2CR1 = C_PWM2_Active_Hi;
	P3CR1 = C_PWM3_Active_Hi;
	*/
	
	TM5RH = 0;
	//TMR5  = 100;
	TMR5  = 100;
	//PWM5DUTY  = 10;
	//T5CR2 = C_PS5_EN | C_PS5_Div32;	//tmr5 source=instruction, prescaler off	
	T5CR2 = C_PS5_EN | C_PS5_Div4;
	T5CR1 = C_TMR5_Reload; //timer5 enable, reload.
	PWMDB = 0x00; 		//deand band = 1 CPU cycle
  	//CCPCON = C_CCP_PWM5_HalfOut | C_CCP_PWM5_All_ActHigh;		// half-bridge ,P1A active High. P1B active Low.
  	CCPCON = C_CCP_PWM5_SigOut | C_CCP_PWM5_All_ActHigh;
  	
  	TM4RH = 0;
  	//TMR4 = 110;
  	TMR4 = 100;
  	//PWM4DUTY = 20;
  	//T4CR2 = C_PS4_Dis;
  	//T4CR2 = C_PS4_EN | C_PS4_Div32;
  	T4CR2 = C_PS4_EN | C_PS4_Div4;
  	T4CR1 = C_PWM4_En | C_TMR4_En | C_TMR4_Reload | C_PWM4_Active_Hi;
  	//INTE2 = C_INE_TMR4;
  	
  	TMRH = 0;
  	//TMR1 = 100;
  	//TMR1 = 201;
  	TMR1 = 101;
  	//PWM1DUTY = 50;
  	T1CR1 = C_PWM1_En | C_TMR1_En | C_TMR1_Reload | C_PWM1_Active_Hi;
  	T1CR2 = C_PS1_Div32 | C_PS1_EN;
  	//T1CR2 = C_PS1_Div256 | C_PS1_EN;
  	P3CR1 = C_PWM3_En | C_PWM3_Active_Hi;
  	//PWM3DUTY = 30;
  	
  	P2CR1 = C_PWM2_En | C_PWM2_Active_Hi;
  	//PWM2DUTY = 40;
  	
	updateColor();
}